﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;

public class QuadDisplay : MonoBehaviour {

	string fileName = "CT-MONO2-8-abdo";


	List<byte> pixels8;
	byte[] lut8;

	DicomDecoder dd = new DicomDecoder();

	int imageWidth, imageHeight, bitDepth, samplesPerPixel;
	double winCenter, winWidth;
	bool signedImage;

	int minPixelValue, maxPixelValue;


	int winMin = 0, winMax = 65535;

	public bool invert = true;

	// Use this for initialization
	void Start () {

		pixels8 = new List<byte> ();

		lut8 = new byte[256];

		ReadAndDisplayDicomFile(Application.dataPath + "/" + fileName);
	
	}

	void SetParameters(ref List<byte> arr, int wid, int hei, double windownWidth, double windowCenter, int samplesPerPixel)
	{
		if (samplesPerPixel == 1) {

			//reset value: winMax and winMin used to setup the lookup table
			winMax = Convert.ToInt32(winCenter + 0.5 * winWidth);
			winMin = winMax - Convert.ToInt32(winWidth);

			//Compute look up table
			if (winMax == 0) winMax = 255;

			int range = winMax - winMin;
			if (range < 1)
				range = 1;
			double factor = 255.0 / range;

			for (int i = 0; i < 256; i++) {

				if (i <= winMin)
					lut8 [i] = 0;
				else if (i >= winMax)
					lut8 [i] = 255;
				else
					lut8 [i] = (byte)((i - winMin) * factor);

			}

			//Create texture image
			Color32[] color = new Color32[wid * hei];

			if (invert) {
				for (int i = 0; i < hei; i++) {

					for (int j = 0; j < wid; j++) {

						byte b = lut8 [arr [i * wid + j]];

						color [i * wid + j].r = b;
						color [i * wid + j].g = b;
						color [i * wid + j].b = b;
						color [i * wid + j].a = 1;
					}

				}
			} else {

				for (int i = 0; i < hei; i++) {

					for (int j = 0; j < wid; j++) {

						byte b = lut8 [arr [i * wid + j]];

						color [(hei - i - 1) * wid + j].r = b;
						color [(hei - i - 1) * wid + j].g = b;
						color [(hei - i - 1) * wid + j].b = b;
						color [(hei - i - 1) * wid + j].a = 1;
					}

				}
			}


			Texture2D tex = new Texture2D (wid, hei, TextureFormat.RGB24, false, true);
			tex.SetPixels32 (color);
			tex.Apply ();

			GetComponent<Renderer> ().material.mainTexture = tex;
		}
	}

	void ReadAndDisplayDicomFile(string fileName)
	{
		dd.DicomFileName = fileName;

		TypeOfDicomFile typeofDicomFile = dd.typeofDicomFile;

		if (typeofDicomFile == TypeOfDicomFile.Dicom3File ||
		    typeofDicomFile == TypeOfDicomFile.DicomOldTypeFile) {

			imageWidth = dd.width;
			imageHeight = dd.height;
			bitDepth = dd.bitsAllocated;
			winCenter = dd.windowCenter;
			winWidth = dd.windowWidth;
			samplesPerPixel = dd.samplesPerPixel;
			signedImage = dd.signedImage;

			if (samplesPerPixel == 1 && bitDepth == 8) {

				pixels8.Clear ();

				dd.GetPixels8 (ref pixels8);

				minPixelValue = pixels8.Min ();
				maxPixelValue = pixels8.Max ();

				if (signedImage)
					winCenter -= char.MinValue;

				if (Mathf.Abs ((float)winWidth) < 0.001f)
					winWidth = maxPixelValue - minPixelValue;

				if (winCenter == 0 || minPixelValue > winCenter || maxPixelValue < winCenter)
					winCenter = (maxPixelValue + minPixelValue) / 2;


				SetParameters (ref pixels8, imageWidth, imageHeight, winWidth, winCenter, samplesPerPixel);

			}

		}
	}
}
